package com.pxample.config;


import java.nio.charset.Charset;
import java.util.Arrays;


import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter4;

@Configuration
public class RestAutoConfig {


    // 直连的请求
    @Bean
    RestTemplate directRestTemplate() {
        RestTemplate template = new RestTemplate(RestAutoConfig.newClientHttpRequestFactoryDelegate());
        template.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("utf-8")));
        template.getMessageConverters().add(1, new FastJsonHttpMessageConvert5());
        return template;
    }


    public static class FastJsonHttpMessageConvert5 extends FastJsonHttpMessageConverter4 {
        static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");

        public FastJsonHttpMessageConvert5() {
            setDefaultCharset(DEFAULT_CHARSET);
            setSupportedMediaTypes(
                    Arrays.asList(MediaType.APPLICATION_JSON, new MediaType("application", "*+json")));
        }

    }
    //}

    /**
     * 自定义RestTemplate配置
     * 1、设置最大连接数
     * 2、设置路由并发数
     *
     * @return
     * @author Hux
     */
    public static ClientHttpRequestFactory newClientHttpRequestFactory() {
        PoolingHttpClientConnectionManager pollingConnectionManager = new PoolingHttpClientConnectionManager();
        // 最大连接数
        pollingConnectionManager.setMaxTotal(2000);
        // 单路由的并发数
        pollingConnectionManager.setDefaultMaxPerRoute(100);
        HttpClientBuilder httpClientBuilder = HttpClients.custom();
        httpClientBuilder.setConnectionManager(pollingConnectionManager);
        // 保持长连接配置，需要在头添加Keep-Alive
        httpClientBuilder.setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy());
        HttpClient httpClient = httpClientBuilder.build();

        // httpClient连接底层配置clientHttpRequestFactory
        HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
        clientHttpRequestFactory.setReadTimeout(15000);    // 15s
        clientHttpRequestFactory.setConnectTimeout(5000);  // 连接超时时间 5s
        clientHttpRequestFactory.setConnectionRequestTimeout(1000); // 从线程池中获取线程超时时间 1s
        return clientHttpRequestFactory;
    }

    /**
     * 自定义RestTemplate配置
     * 1、设置最大连接数
     * 2、设置路由并发数
     *
     * @return
     * @author Hux
     */
    public static ClientHttpRequestFactory newClientHttpRequestFactoryDelegate() {
        PoolingHttpClientConnectionManager pollingConnectionManager = new PoolingHttpClientConnectionManager();
        // 最大连接数
        pollingConnectionManager.setMaxTotal(1200);
        // 单路由的并发数
        pollingConnectionManager.setDefaultMaxPerRoute(60);
        HttpClientBuilder httpClientBuilder = HttpClients.custom();
        httpClientBuilder.setConnectionManager(pollingConnectionManager);
        // 保持长连接配置，需要在头添加Keep-Alive
        httpClientBuilder.setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy());
        HttpClient httpClient = httpClientBuilder.build();

        // httpClient连接底层配置clientHttpRequestFactory
        HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
        clientHttpRequestFactory.setReadTimeout(15000); // 15s
        clientHttpRequestFactory.setConnectTimeout(5000);  // 连接超时时间 5s
        clientHttpRequestFactory.setConnectionRequestTimeout(1000); // 从线程池中获取线程超时时间 1s
        return clientHttpRequestFactory;
    }


    /**
     * 自定义RestTemplate配置
     * 1、设置最大连接数
     * 2、设置路由并发数
     *
     * @return
     * @author Hux
     */
    public static ClientHttpRequestFactory envoyClientHttpRequestFactoryDelegate() {
        PoolingHttpClientConnectionManager pollingConnectionManager = new PoolingHttpClientConnectionManager();
        // 最大连接数
        pollingConnectionManager.setMaxTotal(60);
        // 单路由的并发数
        pollingConnectionManager.setDefaultMaxPerRoute(30);
        HttpClientBuilder httpClientBuilder = HttpClients.custom();
        httpClientBuilder.setConnectionManager(pollingConnectionManager);
        // 保持长连接配置，需要在头添加Keep-Alive
        httpClientBuilder.setKeepAliveStrategy(((response, context) -> 20 * 60 * 1000));
        HttpClient httpClient = httpClientBuilder.build();

        // httpClient连接底层配置clientHttpRequestFactory
        HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
        clientHttpRequestFactory.setReadTimeout(15000); // 15s
        clientHttpRequestFactory.setConnectTimeout(5000);  // 连接超时时间 5s
        clientHttpRequestFactory.setConnectionRequestTimeout(1000); // 从线程池中获取线程超时时间 1s
        return clientHttpRequestFactory;
    }

    /**
     * 自定义RestTemplate配置,针对大数据KYC
     * 1、设置最大连接数
     * 2、设置路由并发数
     *
     * @return
     * @author luochunfu
     */
    public static ClientHttpRequestFactory newClientHttpRequestFactoryKyc() {
        PoolingHttpClientConnectionManager pollingConnectionManagerKyc = new PoolingHttpClientConnectionManager();
        // 最大连接数
        pollingConnectionManagerKyc.setMaxTotal(100);
        // 单路由的并发数
        pollingConnectionManagerKyc.setDefaultMaxPerRoute(100);
        HttpClientBuilder httpClientBuilder = HttpClients.custom();
        httpClientBuilder.setConnectionManager(pollingConnectionManagerKyc);
        // 保持长连接配置，需要在头添加Keep-Alive
        httpClientBuilder.setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy());
        HttpClient httpClient = httpClientBuilder.build();

        // httpClient连接底层配置clientHttpRequestFactory
        HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
        clientHttpRequestFactory.setReadTimeout(60000);// KYC 60s
        clientHttpRequestFactory.setConnectTimeout(5000);  // 连接超时时间 5s
        clientHttpRequestFactory.setConnectionRequestTimeout(1000); // 从线程池中获取线程超时时间 1s
        return clientHttpRequestFactory;
    }
}